package com.allwees.bs.module.core.rest;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.allwees.bs.core.modelbase.bo.Bo;
import com.allwees.bs.core.modelbase.req.Queryable;
import com.allwees.bs.core.modelbase.vo.R;
import com.allwees.bs.module.base.service.BoService;
import com.allwees.bs.module.core.dynamic.annotation.DynamicInject;
import com.allwees.core.common.constant.EStatus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 关联单个Bo的API Action基类，每个Action对应一个Bo的API
 *
 * @param <B>
 * @author yangylsky
 */
@Slf4j
@RestController
public abstract class BoCrudApi<B extends Bo, S extends BoService<B>> extends BaseApi {
    /**
     * 由子类提供对应的Bo管理Service
     *
     * @return
     */
    @Autowired
    protected S boService;

    /**
     * 新增BO(参数为Bo子类)
     *
     * @param bo
     * @return
     */
    @PostMapping
    public R create(@RequestBody B bo) {
        boolean success = boService.create(bo);
        return success ? R.ok("创建成功").put("uuid", bo.getUuid()) : R.error("创建失败");
    }

    /**
     * 更新BO(参数为Bo子类)
     *
     * @param bo
     * @return
     */
    @PutMapping
    public R update(@RequestBody B bo) {
        boolean success = boService.updateByUuid(bo);
        return success ? R.ok("更新成功") : R.error("更新失败");
    }

    /**
     * 删除单个BO
     *
     * @param uuid
     * @return
     */
    @DeleteMapping("/{uuid}")
    public R delete(@PathVariable("uuid") String uuid) {
        boolean success = boService.deleteByUuid(uuid);
        return success ? R.ok("删除成功") : R.error("删除失败");
    }

    /**
     * 批量删除BO
     *
     * @param uuids
     * @return
     */
    @DeleteMapping("/batch/{uuids}")
    public R batchDelete(@PathVariable("uuids") String uuids) {
        int successNum = boService.deleteByUuids(StringUtils.split(uuids, ","));
        return R.ok("批量删除成功").put("successNum", successNum);
    }

    /**
     * 查询单个BO
     *
     * @param uuid
     * @return
     */
    @DynamicInject(type = DynamicInject.Type.Category,key = "categoryNo")
    @GetMapping("/{uuid}")
    public R retrieve(@PathVariable("uuid") String uuid) {
        Object retObj = _doRetrieve(uuid);
        return R.ok(retObj);
    }

    /**
     * 禁用
     *
     * @param uuid
     * @return
     */
    @PutMapping("/{uuid}/disable")
    public R disable(@PathVariable String uuid) {
        boService.updateStatusByUuids(EStatus.DISABLED, uuid);
        return R.ok();
    }

    /**
     * 启用
     *
     * @param uuid
     * @return
     */
    @PutMapping("/{uuid}/enable")
    public R enable(@PathVariable String uuid) {
        boService.updateStatusByUuids(EStatus.NORMAL, uuid);
        return R.ok();
    }

    protected Object _doRetrieve(String uuid) {
        return boService.findByUuid(uuid);
    }

    /**
     * 根据条件查询多个BO
     *
     * @param <P>
     * @param req
     * @return
     */
    protected <P extends Queryable<B>> R list(P req) {
        return R.ok(boService.findList(req));
    }

    /**
     * 根据条件查询一个分页BO
     *
     * @param <P>
     * @param page
     * @param req
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    protected <P extends Queryable> R page(Page<B> page, P req) {
        IPage page1 = boService.findPage(page, req);
        afterFindPage(page1);
        return R.ok(page1);
    }

    protected <T> void afterFindPage(IPage<T> page) {

    }
}
